package com.nacos.springboot.snail.util;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description TODO
 * @Author xueguoping
 * @Date 2021/5/8 16:12
 */
public class SentinelUtil {

	private static void doSomethin(){
		try (Entry entry = SphU.entry("doSomething")){
			System.out.println("hello world"+System.currentTimeMillis());
		}catch (BlockException ex){
			System.out.println("limit");
		}
	}

	private static void initFlowRules(){
		List<FlowRule> rules = new ArrayList<>();
		FlowRule rule = new FlowRule();
		rule.setResource("doSomething");//需要保护的资源  必须和SphU.entry中使用的名称一致
		rule.setGrade(RuleConstant.FLOW_GRADE_QPS);//限流阙值类型 QPS模式 1 并发线程数模式 0
		rule.setCount(10);//限流阙值
		rule.setLimitApp("default");//是否需要针对调用来源进行限流，默认是default,即不区分调用来源
		rule.setStrategy(RuleConstant.STRATEGY_CHAIN);//调用关系限流策略--直接、链路、关联
		rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);//流控行为，包括CONTROL_BEHAVIOR_DEFAULT直接拒绝、CONTROL_BEHAVIOR_RATE_LIMITER排队等待、CONTROL_BEHAVIOR_WARM_UP慢启动模式，默认直接拒绝
		rule.setClusterMode(false);//是否是集群限流，默认为否
		rules.add(rule);
		FlowRuleManager.loadRules(rules);
	}

	private static void initDegradeRule(){
		//RT （Round Trip Time） 平均响应时间：当1s内持续进入N个请求，对应时刻的平均响应时间（秒级）均超过阈值（count,以ms为单位），
		//那么接下来的时间窗口（DegradeRule中的timeWindow,以s为单位）之内，对这个方法的调用都会自动地熔断（抛出DegradeException）。
		//注意Sentinel默认统计的RT上限是4900ms,超出此阈值的都会算作4900ms,若需要变更此上限可以通过配置项-Dcsp.sentinel.statistic.max.rt=XX来配置。
		List<DegradeRule> rules = new ArrayList<>();
		DegradeRule degradeRule = new DegradeRule();
		degradeRule.setResource("KEY");
		degradeRule.setCount(10);
		//DEGRADE_GRADE_RT
		//DEGRADE_GRADE_EXCEPTION_RATIO 异常比例 如果每秒资源数>=minRequestAmount(默认值为5)，并且每秒的异常总数占总通过量的比例超过阈值count
		// （count的取值范围是[0.0，1.0]，代表0%-100%），则资源进入降级状态。同样在接下来的timeWindow之内，对这个方法的调用都会自动触发熔断
		//DEGRADE_GRADE_EXCEPTION_COUNT异常数 当资源最近一分钟的异常数超过阈值之后，会自动触发熔断。需要注意的是，如果timeWindow小于60s,则结束
		//熔断状态后，仍然可能再进入熔断状态。
		degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);//熔断策略 支持秒级RT、秒级异常比例、分钟级异常数。默认秒级RT
		degradeRule.setTimeWindow(10);//熔断降级的时间窗口，单位为s.也就是触发熔断降级之后多长时间内自动熔断
		degradeRule.setMinRequestAmount(5);//触发的异常熔断最小请求数，请求数小于该值即使异常比例超出阈值，值也不会触发熔断，默认值是5
		degradeRule.setRtSlowRequestAmount(5);//在RT模式下，1s内持续多少个请求的平均RT超出阈值后触发熔断，默认值5
		rules.add(degradeRule);
		DegradeRuleManager.loadRules(rules);
	}

	public static void main(String[] args) {
		initFlowRules();
		while (true){
			doSomethin();
		}
	}
}
